﻿using Common.Infrastructure.Utils;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using System.Collections.Generic;
using System.Linq;

namespace Common.Infrastructure.Service
{
    public class MessageService : IMessageService
    {
        private readonly IHttpContextAccessor contextAccessor;
        private readonly string lang;
        private readonly List<ApiActionMessage> messages = new List<ApiActionMessage>();

        public MessageService(IConfiguration configuration, IHttpContextAccessor accessor)
        {
            lang = configuration["Lang"];
            this.contextAccessor = accessor;
            var l = GetContextLang();
            if (!string.IsNullOrEmpty(l))
            {
                this.lang = l;
            }
        }

        public string Lang
        {
            get { return this.lang; }
        }

        public void AddError(string message)
        {
            AddMessage(EFMessageType.Error, string.Empty, message);
        }

        public void AddError(string code, params object[] objs)
        {
            AddMessage(EFMessageType.Error, code, GetMessage(code, objs));
        }

        public void AddWarning(string message)
        {
            AddMessage(EFMessageType.Warning, string.Empty, message);
        }

        public void AddWarning(string code, params object[] objs)
        {
            AddMessage(EFMessageType.Warning, code, GetMessage(code, objs));
        }

        public void AddInfomation(string message)
        {
            AddMessage(EFMessageType.Infomation, string.Empty, message);
        }

        public void AddInfomation(string code, params object[] objs)
        {
            AddMessage(EFMessageType.Infomation, code, GetMessage(code, objs));
        }

        public string GetMessage(string code, params object[] objs)
        {
            var foramt = MessageStorageUtils.GetMessageFormat(code, this.lang);
            if (objs != null && objs.Any())
            {
                return string.Format(foramt, objs);
            }

            return foramt;
        }

        public void ThrowError(string code, params object[] objs)
        {
            string m = GetMessage(code, objs);
            throw new CodeException(code, m);
        }

        public bool HasError()
        {
            return this.messages.Any(t => t.MessageType == EFMessageType.Error);
        }

        public List<ApiActionMessage> GetMessages()
        {
            return this.messages;
        }

        public void AddActionMessage(ApiActionMessage actionMessage)
        {
            if (actionMessage != null)
            {
                this.messages.Add(actionMessage);
            }
        }

        public void MessageToActionResult<T>(ApiActionResult<T> actionResult)
        {
            if (actionResult == null)
            {
                return;
            }

            if (messages == null || !messages.Any())
            {
                return;
            }

            actionResult.Messages.AddRange(messages);
            if (actionResult.Messages.Any(t => t.MessageType == EFMessageType.Error))
            {
                actionResult.IsSuccess = false;
            }
        }

        private void AddMessage(EFMessageType type, string code, string message)
        {
            messages.Add(new ApiActionMessage()
            {
                Code = code,
                MessageType = type,
                Message = message,
            });
        }

        private string GetContextLang()
        {
            try
            {
                var lang = this.contextAccessor?.HttpContext?.Request?.Headers["Lang"].ToString()?.Trim();
                return lang;
            }
            catch
            {
            }

            return string.Empty;
        }
    }
}
